<?php

namespace common\models;

use common\components\OrderBehavior;
use common\helpers\commonApi;
use common\helpers\TransformApi;
use EasyWeChat\Factory;
use Yii;

/**
 * This is the model class for table "{{%activity_enter}}".
 *
 * @property int $id
 * @property string|null $orderid 订单号
 * @property int|null $act_id 活动id
 * @property int|null $userid 用户id
 * @property string|null $info 活动信息
 * @property float|null $amount 金额
 * @property float|null $discount_amount 优惠金额
 * @property float|null $pay_amount 支付金额
 * @property int|null $num 数量
 * @property string|null $create_time 创建时间
 * @property string|null $update_time 修改时间
 * @property string|null $callback_time 回调时间
 * @property string|null $callback_info 回调信息
 * @property int|null $status 状态
 * @property int|null $is_join 是否参加
 */
class ActivityEnter extends BaseModel
{
    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return '{{%activity_enter}}';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['act_id', 'userid', 'status', 'is_join','num'], 'integer'],
            [['info', 'callback_info'], 'string'],
            [['orderid'], 'string','max'=>255],
            [['amount', 'discount_amount', 'pay_amount'], 'number'],
            [['create_time', 'update_time', 'callback_time'], 'safe'],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'act_id' => '活动id',
            'userid' => '用户id',
            'orderid' => '订单号',
            'info' => '活动信息',
            'amount' => '金额',
            'discount_amount' => '优惠金额',
            'pay_amount' => '支付金额',
            'num' => '数量',
            'create_time' => '创建时间',
            'update_time' => '修改时间',
            'callback_time' => '回调时间',
            'callback_info' => '回调信息',
            'status' => '状态',
            'is_join' => '是否参加',
        ];
    }
    /**
     * 创建订单号
     * @return string
     */
    public static function markOrderid()
    {
        $orderId = time() . '' . rand(1000, 9999);
        if (self::find()->where(['orderid' => $orderId])->exists()) {
            $orderId = self::markOrderid();
        }
        return $orderId;
    }

    /**
     * 报名
     * @param $userid
     * @param $act_id
     * @param $num
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function enter($userid,$act_id,$num)
    {
        $activity = Activity::find()->where(['id'=>$act_id])->one();
        if (!$activity){
            return commonApi::message('活动已下架',false);
        }

        $isEnter = (new Activity())->isEnter($userid,$act_id,$activity->start_time,$activity->end_time,$activity->status,$activity->delete,$activity->surplus);
        if (!$isEnter['status']){
            return commonApi::message('活动'.$isEnter['status_title'],false);
        }
        $activity->price = $activity->price??0;
        $price = $activity->price*$num;
        $system = System::getModel();
        $activity_discount = $system->activity_discount??0;
        $act_cancel = $system->act_cancel??0;
        if ($activity_discount>0){
            $huiyuan = (new User())->isHuiyuan($userid,'','',0);
            if ($huiyuan){
                $price = $price*($activity_discount/10);
                $price = TransformApi::decimalPoint($price);
            }
        }
        $openid = User::find()->where(['id'=>$userid])->select(['openid'])->scalar();
        if (!$openid){
            return commonApi::message('请授权',false);
        }
        $model = new self();
        $model->orderid = self::markOrderid();
        $model->act_id = $act_id;
        $model->userid = $userid;
        $model->info = json_encode($activity->toArray());
        $model->amount = $activity->price*$num;
        $model->discount_amount = $model->amount-$price;
        $model->pay_amount = $price;
        $model->num = $num;
        $model->status = 0;
        $model->is_join = 0;
        $activity->surplus -= $num;
        $tran = Yii::$app->db->beginTransaction();
        try{
            if ($model->pay_amount<=0){
                $model->status = 1;
                $model->callback_time = date('Y-m-d H:i:s');
                if ($model->save()&&$activity->save()){
                    $tran->commit();
                    return commonApi::message('报名成功',true,['is_pay'=>0]);
                }
                throw new \Exception(commonApi::getModelError($model));
            }
            $config = [
                'app_id'             => $system->a_appid,
                'mch_id'             => $system->mch_id,
                'key'                => $system->pay_key,
                'notify_url'         => Yii::$app->request->hostInfo.'/api/pay-notify/activity'
            ];
            $app = Factory::payment($config);
            $result = $app->order->unify([
                'body' => '活动报名-'.$activity->name,
                'out_trade_no' => $model->orderid,
                'total_fee' => $model->pay_amount*100,
                'trade_type' => 'JSAPI',
                'openid' => $openid,
            ]);
            if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS' && isset($result['prepay_id'])){
                if ($model->save()&&$activity->save()){
                    $config = $app->jssdk->bridgeConfig($result['prepay_id'], false); // 返回数组
                    $config['is_pay'] = 1;
                    $tran->commit();
                    if ($act_cancel>0){
//                        Yii::$app->queue->delay($act_cancel*60)->push(new OrderBehavior([
//                            'method' => OrderBehavior::Act_CANCEL,
//                            'params' => ['id'=>$model->id],
//                        ]));
                    }
                    return commonApi::message('等待支付',true,$config);
                }
                throw new \Exception(commonApi::getModelError($model));
            }
            $ms = empty($result['err_code_des'])?$result['return_msg']:$result['err_code_des'];
            throw new \Exception($ms);
        }catch (\Exception $e){
            $tran->rollBack();
            return commonApi::message($e->getMessage(),false);
        }
    }
}
